/*
 * 功能：公告服务类，提供公告相关的业务逻辑操作
 * 作者：张杨(Sunny)
 * 日期： 2024/11/11 上午11:28
 */
package com.example.springboot.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot.common.Result;
import com.example.springboot.entity.Notice;
import com.example.springboot.entity.User;
import com.example.springboot.mapper.NoticeMapper;
import com.example.springboot.utils.TokenUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class NoticeService extends ServiceImpl<NoticeMapper, Notice> {

    @Resource
    NoticeMapper noticeMapper;


    /**
     * 添加公告信息
     *
     * @param notice 要添加的公告对象
     * @return 返回操作结果
     */
    public Result addNotice(Notice notice) {
        User currentUser = TokenUtils.getCurrentUser(); // 获取当前登录用户
        if (currentUser != null) {
            notice.setUsername(currentUser.getUsername());
        } else {
            return Result.error("用户未登录");
        }
        notice.setTime(DateUtil.today());
        noticeMapper.insert(notice);
        return Result.success();
    }


    /**
     * 获取所有公开的公告信息
     *
     * @return 公开公告的列表
     */
    public List<Notice> getOpenNotices() {
        QueryWrapper<Notice> queryWrapper = new QueryWrapper<Notice>().orderByDesc("id");
        queryWrapper.eq("open", 1);
        return noticeMapper.selectList(queryWrapper);
    }


    /**
     * 分页获取公告信息
     *
     * @param pageNum  当前页码
     * @param pageSize 每页显示的记录数
     * @param title    公告标题的模糊查询条件
     * @param username 公告发布者的模糊查询条件
     * @return 分页后的公告信息
     */
    public Page<Notice> getNoticesByPage(Integer pageNum, Integer pageSize, String title, String username) {
        QueryWrapper<Notice> queryWrapper = new QueryWrapper<Notice>().orderByDesc("id");  // 默认倒序，让最新的数据在最上面
        queryWrapper.like(StrUtil.isNotBlank(title), "title", title);
        queryWrapper.like(StrUtil.isNotBlank(username), "username", username);
        return noticeMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper);
    }


    /**
     * 导出评论信息到Excel文件
     *
     * @param content    用户名（模糊查询）
     * @param createTime 创建时间（模糊查询）
     * @param ids        评论ID列表（精确查询）
     * @param response   HTTP响应对象
     * @throws IOException 如果IO操作失败
     */
    public void exportData(String content, String createTime, String ids, HttpServletResponse response) throws IOException {
        ExcelWriter writer = ExcelUtil.getWriter(true); // 创建Excel写入器
        List<Notice> list; // 用于存储查询结果的列表
        QueryWrapper<Notice> queryWrapper = new QueryWrapper<>(); // 创建查询条件包装器

        // 如果ids参数不为空，则按ID筛选数据
        if (StrUtil.isNotBlank(ids)) {
            List<Integer> idsArr1 = Arrays.stream(ids.split(",")).map(Integer::valueOf).collect(Collectors.toList());
            queryWrapper.in("id", idsArr1);
        } else {
            // 否则按用户名或创建时间筛选数据
            queryWrapper.like(StrUtil.isNotBlank(content), "content", content);
            queryWrapper.like(StrUtil.isNotBlank(createTime), "createTime", createTime);
        }
        list = noticeMapper.selectList(queryWrapper); // 执行查询
        writer.write(list, true); // 将查询结果写入Excel

        // 设置响应头，指定文件类型和文件名
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename="
                + URLEncoder.encode("公告信息表", "UTF-8") + ".xlsx");

        ServletOutputStream outputStream = response.getOutputStream(); // 获取响应输出流
        writer.flush(outputStream, true); // 将Excel数据刷新到输出流
        writer.close(); // 关闭写入器
        outputStream.flush(); // 刷新输出流
        outputStream.close(); // 关闭输出流
    }

    // 导入数据的方法
    @Transactional
    public Result importData(MultipartFile file) throws IOException {
        ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
        List<Notice> noticeList = reader.readAll(Notice.class);
        // 写入数据到数据库
        try {
            saveBatch(noticeList);
            return Result.success();
        } catch (Exception e) {
            return Result.error("数据批量导入错误");
        }
    }
}
